﻿namespace Pna.Buttler.Speech.Recognition
{
    using System.Threading;
    using System;
    using System.Speech.Recognition;

    /// <summary>
    /// The recognizer engine.
    /// </summary>
    public class RecognizerEngine
    {
        /// <summary>
        /// The engine.
        /// </summary>
        private readonly SpeechRecognitionEngine engine;

        /// <summary>
        /// Initializes a new instance of the <see cref="RecognizerEngine"/> class.
        /// </summary>
        public RecognizerEngine()
        {
            this.engine = new SpeechRecognitionEngine(Thread.CurrentThread.CurrentCulture);
        }

        /// <summary>
        /// The heard.
        /// </summary>
        public event Action<string> Heard = h => { };

        /// <summary>
        /// The initialize.
        /// </summary>
        /// <param name="listenTo">
        /// The listen to.
        /// </param>
        public void Initialize(params string[] listenTo)
        {
            this.engine.RequestRecognizerUpdate(); // request for recognizer update

            var grammarBuilder = new GrammarBuilder(new Choices(listenTo));
            var grammar = new Grammar(grammarBuilder);
            this.engine.LoadGrammar(grammar); // load a grammar

            this.engine.SpeechRecognized += this.SpeechRecognized;

            // set the input of the speech recognizer to the default audio device
            this.engine.SetInputToDefaultAudioDevice();

            // recognize speech asynchronous
            this.engine.RecognizeAsync(RecognizeMode.Multiple);
        }

        /// <summary>
        /// The speech recognized.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
        {
            this.Heard(e.Result.Text);
        }
    }
}
